#ifndef MMC5983MA_H
#define MMC5983MA_H

#include <Wire.h>

// MMC5983MA I2C address
#define MMC5983MA_ADDR          0x30

// Register definitions
#define MMC5983MA_PROD_ID       0x00
#define MMC5983MA_XOUT0         0x00
#define MMC5983MA_XOUT1         0x01
#define MMC5983MA_YOUT0         0x02
#define MMC5983MA_YOUT1         0x03
#define MMC5983MA_ZOUT0         0x04
#define MMC5983MA_ZOUT1         0x05
#define MMC5983MA_TOUT          0x06
#define MMC5983MA_STATUS        0x07
#define MMC5983MA_CONTROL_0     0x08
#define MMC5983MA_CONTROL_1     0x09
#define MMC5983MA_CONTROL_2     0x0A
#define MMC5983MA_CONTROL_3     0x0B
#define MMC5983MA_INT_CTRL      0x0C
#define MMC5983MA_ID            0x39

// Status register bits
#define MMC5983MA_STATUS_DRDY   0x01
#define MMC5983MA_STATUS_OVR    0x02
#define MMC5983MA_STATUS_DOR    0x04

// Control 0 register bits
#define MMC5983MA_CONTROL0_TM_M   0x80
#define MMC5983MA_CONTROL0_TM_S   0x40
#define MMC5983MA_CONTROL0_TM_T   0x20
#define MMC5983MA_CONTROL0_SRST   0x08

// Control 1 register bits
#define MMC5983MA_CONTROL1_AUTO_SR_EN   0x10
#define MMC5983MA_CONTROL1_EN_CMM       0x08
#define MMC5983MA_CONTROL1_SET         0x02
#define MMC5983MA_CONTROL1_RESET       0x01

// Control 2 register bits
#define MMC5983MA_CONTROL2_LOW_POWER   0x80
#define MMC5983MA_CONTROL2_FREQ_0      0x40
#define MMC5983MA_CONTROL2_FREQ_1      0x20
#define MMC5983MA_CONTROL2_FREQ_2      0x10
#define MMC5983MA_CONTROL2_BW_0        0x02
#define MMC5983MA_CONTROL2_BW_1        0x01

class MMC5983MA {
public:
    MMC5983MA();
    ~MMC5983MA();
    
    bool begin(TwoWire *wire = &Wire, uint8_t addr = MMC5983MA_ADDR);
    bool isConnected();
    
    void startSingleMeasurement();
    bool isDataReady();
    
    void readMagneticField(int16_t *x, int16_t *y, int16_t *z);
    void readMagneticField(float *x, float *y, float *z);
    
    float readTemperature();
    
    void setReset();
    void setSet();
    void setAutoMeasurement(bool enable);
    void cal();
    void peeling();
    float get_heading();
    
private:
    TwoWire *_wire;
    uint8_t _addr;
    
    void writeRegister(uint8_t reg, uint8_t value);
    uint8_t readRegister(uint8_t reg);
    void readRegisters(uint8_t reg, uint8_t *data, size_t len);
};

#endif // MMC5983MA_H